#!/bin/bash
# 修复XSAN项目头文件包含和类型定义问题的脚本

set -e

echo "开始修复XSAN项目头文件包含问题..."

# 检查xsan_error.h是否存在
if [ -f "include/xsan_error.h" ]; then
    echo "更新include/xsan_error.h文件..."
    cat > include/xsan_error.h << EOF
/**
 * XSAN 错误类型定义
 */
#ifndef XSAN_ERROR_H
#define XSAN_ERROR_H

/**
 * XSAN 错误代码类型
 */
typedef enum {
    XSAN_SUCCESS = 0,
    XSAN_OK = 0,                      /* XSAN_OK 作为 XSAN_SUCCESS 的别名 */
    XSAN_ERROR_INVALID_PARAM = -1,
    XSAN_ERROR_NO_MEMORY = -2,
    XSAN_ERROR_IO = -3,
    XSAN_ERROR_NOT_FOUND = -4,
    XSAN_ERROR_ALREADY_EXISTS = -5,
    XSAN_ERROR_PERMISSION = -6,
    XSAN_ERROR_BUSY = -7,
    XSAN_ERROR_TIMEOUT = -8,
    XSAN_ERROR_NOT_SUPPORTED = -9,
    XSAN_ERROR_DEVICE_ERROR = -10,
    XSAN_ERROR_NETWORK = -11,
    XSAN_ERROR_CLUSTER = -12,
    XSAN_ERROR_NETWORK_DOWN = -13,    /* 网络连接不可用 */
    XSAN_ERROR_CONNECTION_LOST = -14, /* 连接已断开 */
    XSAN_ERROR_SYSTEM = -15,          /* 系统错误 */
    XSAN_ERROR_GENERIC = -16,         /* 通用错误 */
    XSAN_ERROR_NOT_INITIALIZED = -17, /* 模块未初始化 */
    XSAN_ERROR_THREAD_CONTEXT = -18,  /* 线程上下文错误 */
    XSAN_ERROR_INSUFFICIENT_SPACE = -19, /* 空间不足 */

    /* 存储相关错误 */
    XSAN_ERROR_STORAGE_IO = -40,
    XSAN_ERROR_DEVICE_NOT_FOUND = -41,
    XSAN_ERROR_VOLUME_NOT_FOUND = -42,
    
    /* 配置相关错误 */
    XSAN_ERROR_CONFIG_PARSE = -60,
    XSAN_ERROR_CONFIG_INVALID = -61,
    
    /* 任务相关错误 */
    XSAN_ERROR_TASK_FAILED = -80,
    XSAN_ERROR_TASK_CANCELLED = -81,
    
    /* 虚拟化相关错误 */
    XSAN_ERROR_VM_NOT_FOUND = -100,

    XSAN_ERROR_UNKNOWN = -999
} xsan_error_t;

/**
 * 将系统errno转换为xsan_error_t类型
 */
xsan_error_t xsan_error_from_errno(int err);

/**
 * 获取错误描述字符串
 */
const char *xsan_error_to_string(xsan_error_t err);

#endif /* XSAN_ERROR_H */
EOF
    echo "更新xsan_error.h完成"
else
    echo "创建缺失的xsan_error.h文件..."
    mkdir -p include
    cat > include/xsan_error.h << EOF
/**
 * XSAN 错误类型定义
 */
#ifndef XSAN_ERROR_H
#define XSAN_ERROR_H

/**
 * XSAN 错误代码类型
 */
typedef enum {
    XSAN_SUCCESS = 0,
    XSAN_OK = 0,                      /* XSAN_OK 作为 XSAN_SUCCESS 的别名 */
    XSAN_ERROR_INVALID_PARAM = -1,
    XSAN_ERROR_NO_MEMORY = -2,
    XSAN_ERROR_IO = -3,
    XSAN_ERROR_NOT_FOUND = -4,
    XSAN_ERROR_ALREADY_EXISTS = -5,
    XSAN_ERROR_PERMISSION = -6,
    XSAN_ERROR_BUSY = -7,
    XSAN_ERROR_TIMEOUT = -8,
    XSAN_ERROR_NOT_SUPPORTED = -9,
    XSAN_ERROR_DEVICE_ERROR = -10,
    XSAN_ERROR_NETWORK = -11,
    XSAN_ERROR_CLUSTER = -12,
    XSAN_ERROR_NETWORK_DOWN = -13,    /* 网络连接不可用 */
    XSAN_ERROR_CONNECTION_LOST = -14, /* 连接已断开 */
    XSAN_ERROR_SYSTEM = -15,          /* 系统错误 */
    XSAN_ERROR_GENERIC = -16,         /* 通用错误 */
    XSAN_ERROR_NOT_INITIALIZED = -17, /* 模块未初始化 */
    XSAN_ERROR_THREAD_CONTEXT = -18,  /* 线程上下文错误 */
    XSAN_ERROR_INSUFFICIENT_SPACE = -19, /* 空间不足 */

    /* 存储相关错误 */
    XSAN_ERROR_STORAGE_IO = -40,
    XSAN_ERROR_DEVICE_NOT_FOUND = -41,
    XSAN_ERROR_VOLUME_NOT_FOUND = -42,
    
    /* 配置相关错误 */
    XSAN_ERROR_CONFIG_PARSE = -60,
    XSAN_ERROR_CONFIG_INVALID = -61,
    
    /* 任务相关错误 */
    XSAN_ERROR_TASK_FAILED = -80,
    XSAN_ERROR_TASK_CANCELLED = -81,
    
    /* 虚拟化相关错误 */
    XSAN_ERROR_VM_NOT_FOUND = -100,

    XSAN_ERROR_UNKNOWN = -999
} xsan_error_t;

/**
 * 将系统errno转换为xsan_error_t类型
 */
xsan_error_t xsan_error_from_errno(int err);

/**
 * 获取错误描述字符串
 */
const char *xsan_error_to_string(xsan_error_t err);

#endif /* XSAN_ERROR_H */
EOF
    echo "创建xsan_error.h完成"
fi

# 检查error.c是否存在
if [ ! -d "src/common" ]; then
    mkdir -p src/common
fi

echo "创建或更新错误处理函数实现文件..."
cat > src/common/error.c << EOF
/**
 * XSAN 错误处理函数实现
 */

#include "include/xsan_error.h"
#include <errno.h>
#include <string.h>

/**
 * 将系统errno转换为xsan_error_t类型
 */
xsan_error_t xsan_error_from_errno(int err) {
    switch (err) {
        case 0:
            return XSAN_SUCCESS;
        case EINVAL:
            return XSAN_ERROR_INVALID_PARAM;
        case ENOMEM:
            return XSAN_ERROR_NO_MEMORY;
        case EIO:
            return XSAN_ERROR_IO;
        case ENOENT:
            return XSAN_ERROR_NOT_FOUND;
        case EEXIST:
            return XSAN_ERROR_ALREADY_EXISTS;
        case EACCES:
        case EPERM:
            return XSAN_ERROR_PERMISSION;
        case EBUSY:
            return XSAN_ERROR_BUSY;
        case ETIMEDOUT:
            return XSAN_ERROR_TIMEOUT;
        case ENOSYS:
        case EOPNOTSUPP:
            return XSAN_ERROR_NOT_SUPPORTED;
        case ENODEV:
            return XSAN_ERROR_DEVICE_ERROR;
        case ENETDOWN:
        case ENETUNREACH:
            return XSAN_ERROR_NETWORK;
        default:
            return XSAN_ERROR_UNKNOWN;
    }
}

/**
 * 获取错误描述字符串
 */
const char *xsan_error_to_string(xsan_error_t err) {
    switch (err) {
        case XSAN_SUCCESS:
            return "Success";
        case XSAN_ERROR_INVALID_PARAM:
            return "Invalid parameter";
        case XSAN_ERROR_NO_MEMORY:
            return "Out of memory";
        case XSAN_ERROR_IO:
            return "I/O error";
        case XSAN_ERROR_NOT_FOUND:
            return "Not found";
        case XSAN_ERROR_ALREADY_EXISTS:
            return "Already exists";
        case XSAN_ERROR_PERMISSION:
            return "Permission denied";
        case XSAN_ERROR_BUSY:
            return "Resource busy";
        case XSAN_ERROR_TIMEOUT:
            return "Timeout";
        case XSAN_ERROR_NOT_SUPPORTED:
            return "Not supported";
        case XSAN_ERROR_DEVICE_ERROR:
            return "Device error";
        case XSAN_ERROR_NETWORK:
            return "Network error";
        case XSAN_ERROR_CLUSTER:
            return "Cluster error";
        case XSAN_ERROR_NETWORK_DOWN:
            return "Network connection down";
        case XSAN_ERROR_CONNECTION_LOST:
            return "Connection lost";
        case XSAN_ERROR_SYSTEM:
            return "System error";
        case XSAN_ERROR_GENERIC:
            return "Generic error";
        case XSAN_ERROR_NOT_INITIALIZED:
            return "Module not initialized";
        case XSAN_ERROR_THREAD_CONTEXT:
            return "Thread context error";
        case XSAN_ERROR_INSUFFICIENT_SPACE:
            return "Insufficient space";
        case XSAN_ERROR_STORAGE_IO:
            return "Storage I/O error";
        case XSAN_ERROR_DEVICE_NOT_FOUND:
            return "Device not found";
        case XSAN_ERROR_VOLUME_NOT_FOUND:
            return "Volume not found";
        case XSAN_ERROR_CONFIG_PARSE:
            return "Configuration parse error";
        case XSAN_ERROR_CONFIG_INVALID:
            return "Invalid configuration";
        case XSAN_ERROR_TASK_FAILED:
            return "Task execution failed";
        case XSAN_ERROR_TASK_CANCELLED:
            return "Task cancelled";
        case XSAN_ERROR_VM_NOT_FOUND:
            return "VM not found";
        case XSAN_ERROR_UNKNOWN:
        default:
            return "Unknown error";
    }
}

/**
 * SPDK错误描述字符串（临时解决方案）
 */
const char *spdk_strerror(int err) {
    return strerror(-err);
}
EOF
echo "错误处理函数实现文件创建或更新完成"

# 修复src/include/xsan_ring_buffer.h
echo "更新src/include/xsan_ring_buffer.h，确保包含xsan_error.h..."
if [ -f "src/include/xsan_ring_buffer.h" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/include/xsan_ring_buffer.h; then
        # 修改包含路径
        sed -i 's|#include "xsan_types.h" // For xsan_error_t|#include "include/xsan_error.h" // For xsan_error_t|' src/include/xsan_ring_buffer.h
    fi
fi

# 修复xsan_storage.h
echo "更新include/xsan_storage.h，确保包含xsan_error.h..."
if [ -f "include/xsan_storage.h" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"xsan_error.h\"" include/xsan_storage.h; then
        # 在包含xsan_types.h后添加包含xsan_error.h
        sed -i '/#include "xsan_types.h"/a #include "xsan_error.h"' include/xsan_storage.h
    fi
fi

# 修复src/include/xsan_hashtable.h
echo "更新src/include/xsan_hashtable.h，确保包含xsan_error.h..."
if [ -f "src/include/xsan_hashtable.h" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/include/xsan_hashtable.h; then
        # 修改包含注释
        sed -i 's|#include "xsan_types.h" // For xsan_error_t|#include "xsan_types.h" // For common types\n#include "include/xsan_error.h" // For xsan_error_t|' src/include/xsan_hashtable.h
    fi
fi

# 修复src/include/xsan_list.h
echo "更新src/include/xsan_list.h，确保包含xsan_error.h..."
if [ -f "src/include/xsan_list.h" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/include/xsan_list.h; then
        # 修改包含注释
        sed -i 's|#include "xsan_types.h" // For xsan_error_t|#include "xsan_types.h" // For common types\n#include "include/xsan_error.h" // For xsan_error_t|' src/include/xsan_list.h
    fi
fi

# 修复src/include/xsan_protocol.h
echo "更新src/include/xsan_protocol.h，确保包含xsan_error.h..."
if [ -f "src/include/xsan_protocol.h" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/include/xsan_protocol.h; then
        # 修改包含路径
        sed -i 's|#include "../../include/xsan_error.h"|#include "include/xsan_error.h"|' src/include/xsan_protocol.h
    fi
fi

# 修复src/include/xsan_node_comm.h
echo "更新src/include/xsan_node_comm.h，修复结构体声明问题..."
if [ -f "src/include/xsan_node_comm.h" ]; then
    # 添加前向声明
    if ! grep -q "typedef struct xsan_connection_ctx xsan_connection_ctx_t;" src/include/xsan_node_comm.h; then
        sed -i '/struct spdk_sock_group;/a \\\n// Forward declaration for connection context\ntypedef struct xsan_connection_ctx xsan_connection_ctx_t;' src/include/xsan_node_comm.h
    fi
    
    # 修改回调函数定义中的结构体引用
    sed -i 's|struct xsan_connection_ctx \*conn_ctx|xsan_connection_ctx_t \*conn_ctx|g' src/include/xsan_node_comm.h
fi

# 修复src/network/socket.c
echo "更新src/network/socket.c，确保包含xsan_error.h..."
if [ -f "src/network/socket.c" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/network/socket.c; then
        # 修改包含路径
        sed -i 's|#include "../../include/xsan_error.h"|#include "include/xsan_error.h"|' src/network/socket.c
    fi
fi

# 修复src/network/xsan_node_comm.c
echo "更新src/network/xsan_node_comm.c，修复SPDK函数调用和错误处理..."
if [ -f "src/network/xsan_node_comm.c" ]; then
    # 检查是否已经包含了xsan_error.h
    if ! grep -q "#include \"include/xsan_error.h\"" src/network/xsan_node_comm.c; then
        # 修改包含路径
        sed -i 's|#include "../../include/xsan_error.h"|#include "include/xsan_error.h"|' src/network/xsan_node_comm.c
    fi
    
    # 修复xsan_error_string为xsan_error_to_string
    sed -i 's|xsan_error_string|xsan_error_to_string|g' src/network/xsan_node_comm.c
    
    # 修复 spdk_net_framework_get_sock_group 为 spdk_sock_group_create
    sed -i 's|g_node_comm_ctx.sock_group_on_reactor = spdk_net_framework_get_sock_group(current_reactor);|g_node_comm_ctx.sock_group_on_reactor = spdk_sock_group_create(NULL);|' src/network/xsan_node_comm.c
    sed -i 's|Failed to get SPDK sock group for reactor|Failed to create SPDK sock group for reactor|' src/network/xsan_node_comm.c
    
    # 修复 spdk_sock_get_peer_addr 为 spdk_sock_getaddr，并添加必要参数
    sed -i 's|spdk_sock_get_peer_addr(sock, host, sizeof(host), &port)|spdk_sock_getaddr(sock, host, sizeof(host), \&port, NULL, 0, NULL)|g' src/network/xsan_node_comm.c
    
    # 添加 _find_connection_ctx_by_sock 函数，替换 spdk_sock_get_cb_arg
    if ! grep -q "_find_connection_ctx_by_sock" src/network/xsan_node_comm.c; then
        # 在 _format_peer_addr 函数后添加 _find_connection_ctx_by_sock 函数
        sed -i '/_format_peer_addr(struct spdk_sock \*sock, char \*buf, size_t len)/a \
\
// 根据 sock 查找对应的 connection_ctx\
static xsan_connection_ctx_t *_find_connection_ctx_by_sock(struct spdk_sock *sock) {\
    if (!sock) return NULL;\
    \
    xsan_connection_ctx_t *conn_ctx = NULL;\
    pthread_mutex_lock(\&g_node_comm_ctx.active_connections_lock);\
    xsan_connection_ctx_t *iter = g_node_comm_ctx.active_connections_head;\
    while (iter) {\
        if (iter->sock == sock) {\
            conn_ctx = iter;\
            break;\
        }\
        iter = iter->next;\
    }\
    pthread_mutex_unlock(\&g_node_comm_ctx.active_connections_lock);\
    return conn_ctx;\
}' src/network/xsan_node_comm.c
    fi
    
    # 修复 spdk_sock_get_cb_arg 为 _find_connection_ctx_by_sock
    sed -i 's|xsan_connection_ctx_t \*conn_ctx = (xsan_connection_ctx_t \*)spdk_sock_get_cb_arg(sock);|xsan_connection_ctx_t \*conn_ctx = _find_connection_ctx_by_sock(sock);|' src/network/xsan_node_comm.c
    
    # 修复 sock_group 的释放
    if ! grep -q "spdk_sock_group_close" src/network/xsan_node_comm.c; then
        sed -i '/g_node_comm_ctx.sock_group_on_reactor = NULL;/i \    if (g_node_comm_ctx.sock_group_on_reactor) {\n        spdk_sock_group_close(\&g_node_comm_ctx.sock_group_on_reactor);\n    }' src/network/xsan_node_comm.c
    fi
fi

echo "修复头文件包含问题完成" 